package com.author.surface;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.border.BevelBorder;
import javax.swing.text.Document;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.text.html.CSS;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.parser.Element;

import com.author.document.style.StyleChangeNotify;

public final class LeftIndentButton extends JButton implements ActionListener {
	/* X and Y coordinates of the visible lines */
	private int					x1, x2;
	private int					y1, y2;

	/* Display properties of the left indent button */
	private static final int	LI_BUTTON_WIDTH		= 32;
	private static final int	LI_BUTTON_HEIGHT	= 32;
	private static final int	LI_BUTTON_FONT_SIZE	= 24;

	/* Font used on the Left Indent button */
	private Font				liButtonFont		= new Font(fontName,
															Font.PLAIN,
															LI_BUTTON_FONT_SIZE);
	private static final String	fontName			= "Monospaced";

	/**
	 * The delta amount by which the left indent of a paragraph increases in
	 * response to a click on the left indent button
	 */
	public static final int		DELTA				= 20;

	public LeftIndentButton() {
		// Set size of the Left Indent button
		setSize(new Dimension(LI_BUTTON_WIDTH, LI_BUTTON_HEIGHT));
		setPreferredSize(getSize());
		setEnabled(true);

		// Set border of the Left Indent button
		setBorder(new BevelBorder(BevelBorder.LOWERED));
		setBorderPainted(false);

		// Set visible properties
		setFont(liButtonFont);
		setToolTipText("Increase Left Indent");
		setFocusable(false);
		setVisible(true);

		// Make left indent button responsive to user click
		addActionListener(this);
	}

	public void paint(Graphics g) {
		super.paint(g);
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);

		g2d.setColor(Color.BLACK);
		x1 = 5;
		y1 = 5;
		x2 = 15;
		y2 = 15;
		g2d.drawLine(x1, y1, x2, y2);
		x1 = 10;
		y1 = 5;
		x2 = 20;
		y2 = 15;
		g2d.drawLine(x1, y1, x2, y2);

		x1 = 15;
		y1 = 15;
		x2 = 5;
		y2 = 25;
		g2d.drawLine(x1, y1, x2, y2);
		x1 = 20;
		y1 = 15;
		x2 = 10;
		y2 = 25;
		g2d.drawLine(x1, y1, x2, y2);
	}

	@Override
	public void actionPerformed(ActionEvent ae) {
		if (ae == null) {
			return;
		}

		if (!(ae.getSource() instanceof JButton)) {
			return;
		}

		/* Get the current position of the dot and the mark in the text pane */
		int dot = TextPane.getDot();
		int mark = TextPane.getMark();

		Float newValue = null;
		if (dot == mark) { /* No selection */
			HTMLDocument htmlDoc = (HTMLDocument) TextPane
					.getTextPaneDocument();
			javax.swing.text.Element paraElem = htmlDoc
					.getParagraphElement(dot);

			Float currentValue = new Float(0);
			if (paraElem.getAttributes()
					.getAttribute(StyleConstants.LeftIndent) != null) {
				currentValue = (Float) paraElem.getAttributes().getAttribute(
						StyleConstants.LeftIndent);
			}

			newValue = new Float(currentValue + DELTA); /*
														 * Add left indent to
														 * the current value
														 */

		} else {

			/*
			 * In case there is a selection it might be possible that the left
			 * indent of the paragraph which contains the dot is different than
			 * the left indent of the paragraph which contains the mark. In such
			 * scenarios we consider the left indent value which is the higher
			 * of the two values
			 */

			HTMLDocument htmlDoc = (HTMLDocument) TextPane
					.getTextPaneDocument();

			javax.swing.text.Element paraElemAtDot = htmlDoc
					.getParagraphElement(dot);
			Float leftIndentValueAtDot = new Float(0);
			if (paraElemAtDot.getAttributes().getAttribute(
					StyleConstants.LeftIndent) != null) {
				leftIndentValueAtDot = (Float) paraElemAtDot.getAttributes()
						.getAttribute(StyleConstants.LeftIndent);
			}

			javax.swing.text.Element paraElemAtMark = htmlDoc
					.getParagraphElement(mark);
			Float leftIndentValueAtMark = new Float(0);
			if (paraElemAtMark.getAttributes().getAttribute(
					StyleConstants.LeftIndent) != null) {
				leftIndentValueAtMark = (Float) paraElemAtMark.getAttributes()
						.getAttribute(StyleConstants.LeftIndent);
			}

			newValue = leftIndentValueAtDot > leftIndentValueAtMark ? new Float(
					leftIndentValueAtDot + DELTA) : new Float(
					leftIndentValueAtMark + DELTA);
		}

		/*
		 * Though currently two different values (old and new) are sent to the
		 * style change notifier object, but the first value (old) will not be
		 * used at all. Two values are sent as a convention, since all methods
		 * in the style change notify object operate on two values. The text
		 * pane which will eventually be responsible for handling the change of
		 * left indent property will first check if the left indent of the
		 * current paragraph is greater than or equal to this new value
		 * requested by the user. If such is the case no action is taken,
		 * otherwise we add the new left indent value for the paragraph, subject
		 * to the maximum allowed value as indicated by the MAXIMUM_LEFT_INDENT
		 * field of the TextPane class
		 */

		StyleChangeNotify styleChangeNotify = StyleChangeNotify
				.getStyleChangeNotify();
		styleChangeNotify.setLeftIndent("0", newValue.toString());
	}
}
